package net.cathackers.devel.scmp.chat.impl.groupchat;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import org.apache.log4j.Logger;

import net.cathackers.devel.scmp.auth.interfaces.UserID;
import net.cathackers.devel.scmp.chat.exceptions.ConflictingNicknameException;
import net.cathackers.devel.scmp.factories.SCMPFactory;
import net.cathackers.devel.scmp.xmpp.PresencePacket;

public class GroupChat {
    private Hashtable<String, UserID> users_;
    private Hashtable<UserID, String> nicknames_;
    private Hashtable<UserID, PresencePacket> presences_;
    private UserID groupJID_;
    private Logger logger_;

    public GroupChat(UserID groupJID) {
	users_         = new Hashtable<String, UserID>();
	logger_        = SCMPFactory.getLogger(this);
	nicknames_     = new Hashtable<UserID, String>();
	presences_     = new Hashtable<UserID, PresencePacket>();
	this.groupJID_ = groupJID;
    }
    
    public UserID getGroupID() {
	return groupJID_;
	
    }

    /**
     * this method will help us to know if the nickname already exists or not
     * also we need to make sure that the nickname matches the sender`s JabberID
     * 
     * @param nickName
     * @param sender
     * @return
     * @throws ConflictingNicknameException 
     */
    public boolean isExist(String nickname, UserID sender) throws ConflictingNicknameException {
	boolean ret = false;
	if (users_.containsKey(nickname)) {
	    if (users_.get(nickname).equals(sender)) {
		ret = true;
	    } else {
		throw new ConflictingNicknameException("this nickname already in use");
	    }
	}
	return ret;
    }

    /**
     * we will cache the UserID of the sender with the his nickname
     * 
     * @param nickname
     * @param sender
     */
    public void addUser(String nickname, UserID sender) {
	if (!users_.containsKey(nickname)) {
	    users_.put(nickname, sender);
	    nicknames_.put(sender, nickname);
	} else {
	    logger_.debug("The user " + nickname + " exists ");
	}
    }

    /**
     * remove this user from this group
     * 
     * @param sender
     */
    public void removeUser(UserID sender) {
	if (nicknames_.containsKey(sender)) {
	    String nickname = nicknames_.get(sender);
	    users_.remove(nickname);
	    nicknames_.remove(sender);
	    presences_.remove(sender);
	    logger_.debug("The user " + nickname + " removed ");
	}
    }

    /**
     * get the presence of all existing group members in this group
     * 
     * @return
     */
    public PresencePacket[] getAllUserPresences() {
	return presences_.values().toArray(new PresencePacket[presences_.size()]);
    }

    public String getNickname(UserID sender) {
	String ret = null;
	if (sender != null) {
	    ret = nicknames_.get(sender);
	}
	return ret;
    }

    public void updatePresence(UserID sender, PresencePacket presence) {
	if (sender != null) {
	    presences_.put(sender, presence);
	    logger_.debug("update the presence of " + sender.getCanonicalName());
	}
    }

    public boolean isEmpty() {
	boolean ret = false;
	if (users_.isEmpty() && nicknames_.isEmpty() && presences_.isEmpty()) {
	    ret = true;
	    logger_.debug("The group is empty");
	}
	return ret;
    }

    public UserID getUserID(String nickname) {
	UserID ret = null;
	if (nickname != null) {
	    ret = users_.get(nickname);
	}
	return ret;
	
    }

    public List<UserID> getAllUsers() {
	List<UserID> ret = new ArrayList<UserID>(users_.values());
	return ret;
    }

}
